package com.kun.companion.core.aop;

import com.kun.companion.core.aop.annotation.Interceptor;
import com.kun.companion.core.domain.Primitives;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 拦截器协调器：负责统一管理所有AOP拦截器，实现注解驱动的拦截逻辑
 * <p>
 * 优化特性：
 * 1. 支持方法级和类级注解
 * 2. 支持元注解继承机制
 * 3. 线程安全的缓存管理
 * 4. 拦截器优先级控制
 * 5. 提前返回处理机制
 * ┌─────────────┐   ┌───────────────┐
 * │  前置处理     │←─┤ 按order升序执行 │
 * └─────────────┘   └───────────────┘
 * ↓
 * ┌─────────────┐
 * │ 执行原始方法  │
 * └─────────────┘
 * ↓
 * ┌─────────────┐   ┌───────────────┐
 * │  后置处理     │←─┤ 按order降序执行 │
 * └─────────────┘   └───────────────┘
 * ↓
 * ┌─────────────┐
 * │ 返回结果处理  │
 * └─────────────┘
 *
 * @author gzc
 */
public class InterceptorCoordinator {
    /**
     * 全局拦截器列表（线程安全，按order排序）
     */
    private static final List<BeanInterceptor> GLOBAL_INTERCEPTORS = new CopyOnWriteArrayList<>();
    /**
     * 注解-拦截器缓存（Key: 注解类型，Value: 已排序的拦截器列表）
     */
    private static final Map<Class<? extends Annotation>, List<BeanInterceptor>> INTERCEPTOR_CACHE = new ConcurrentHashMap<>();

    /**
     * 注册全局拦截器（线程安全）
     *
     * @param interceptor 要注册的拦截器实例
     */
    public static synchronized void register(BeanInterceptor interceptor) {
        // 拦截器去重检查
        if (GLOBAL_INTERCEPTORS.stream().noneMatch(i -> i.getClass() == interceptor.getClass())) {
            GLOBAL_INTERCEPTORS.add(interceptor);
            // 按order值升序排序（数值越小优先级越高）
            GLOBAL_INTERCEPTORS.sort(Comparator.comparingInt(BeanInterceptor::getOrder));
            // 清空缓存保证数据一致性
            INTERCEPTOR_CACHE.clear();
        }
    }

    /**
     * AOP核心协调方法（通过ByteBuddy字节码增强调用）
     *
     * @param method 被拦截的原始方法
     * @param zuper  原始方法调用入口
     * @param args   方法参数列表
     * @return 方法执行结果
     */
    @RuntimeType
    public static Object coordinate(
            @Origin Method method,
            @SuperCall Callable<?> zuper,
            @AllArguments Object[] args) throws Exception {

        // 获取匹配的拦截器列表（已排序）
        List<BeanInterceptor> interceptors = getMatchingInterceptors(method);
        if (interceptors.isEmpty()) {
            // 无拦截器直接执行原方法
            return zuper.call();
        }

        try {
            // 前置处理（按注册顺序执行）
            for (BeanInterceptor interceptor : interceptors) {
                if (!interceptor.before(method, args)) {
                    // 拦截器阻断请求
                    return handleEarlyReturn(method);
                }
            }

            // 执行原始方法
            Object result = zuper.call();

            // 后置处理（逆序执行，类似FilterChain）
            for (int i = interceptors.size() - 1; i >= 0; i--) {
                result = interceptors.get(i).after(method, result);
            }

            return result;
        } catch (Exception e) {
            // 异常处理（所有拦截器都会收到异常通知）
            interceptors.forEach(interceptor -> interceptor.onException(method, e));
            throw e;
        }
    }

    /**
     * 获取匹配的拦截器列表（包含方法注解和类注解）
     */
    private static List<BeanInterceptor> getMatchingInterceptors(Method method) {
        // 合并方法注解和类注解（包含元注解）
        Set<Class<? extends Annotation>> annotations = new LinkedHashSet<>();

        // 处理方法级别注解
        collectAnnotations(method.getAnnotations(), annotations);

        // 处理类级别注解
        collectAnnotations(method.getDeclaringClass().getAnnotations(), annotations);
        // 去重（可能多个注解关联同一拦截器）
        return annotations.stream()
                .flatMap(annoType -> getInterceptorsForAnnotation(annoType).stream())
                .distinct()
                .collect(Collectors.toList());
    }

    /**
     * 递归收集注解及其元注解（深度优先搜索）
     */
    private static void collectAnnotations(Annotation[] annotations,
                                           Set<Class<? extends Annotation>> collector) {
        for (Annotation annotation : annotations) {
            Class<? extends Annotation> annoType = annotation.annotationType();
            // 防止循环引用
            if (collector.add(annoType)) {
                collectAnnotations(annoType.getAnnotations(), collector);
            }
        }
    }

    /**
     * 获取绑定指定注解的拦截器（带缓存机制）
     */
    private static List<BeanInterceptor> getInterceptorsForAnnotation(Class<? extends Annotation> annoType) {
        return INTERCEPTOR_CACHE.computeIfAbsent(annoType, key ->
                GLOBAL_INTERCEPTORS.stream()
                        .filter(interceptor -> {
                            Interceptor meta = interceptor.getClass().getAnnotation(Interceptor.class);
                            return meta != null && Arrays.asList(meta.bind()).contains(key);
                        })
                        .collect(Collectors.toList())
        );
    }

    /**
     * 处理提前返回逻辑（返回类型安全值）
     */
    private static Object handleEarlyReturn(Method method) {
        Class<?> returnType = method.getReturnType();
        if (returnType == void.class) {
            return null;
        }
        // 处理原始类型默认值
        return Primitives.defaultValue(returnType);
    }

    /**
     * 获取已注册的注解类型集合
     */
    public static Set<Class<? extends Annotation>> getRegisteredAnnotations() {
        return GLOBAL_INTERCEPTORS.stream()
                .map(interceptor -> interceptor.getClass().getAnnotation(Interceptor.class))
                .filter(Objects::nonNull)
                .flatMap(meta -> Arrays.stream(meta.bind()))
                .collect(Collectors.toCollection(LinkedHashSet::new));
    }
}